//	水波图

import React from 'react';
import { Liquid, LiquidOptions } from '@antv/g2plot';
import { WD_TYPE } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { getComponentData } from 'src/services/AnalyseManage';
import PubSub from 'pubsub-js';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';

export default class LiquidChart extends ChartService {

	state = {
		chartEl: null,
		name: '指标',
		percent: 0.25,
		eventToken: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	getConfig = (): LiquidOptions => {
		let { config } = this.props;
		return {
			percent: this.state.percent,
			autoFit: true,
			statistic: {
				title: config.style.isShowLiquidLabel === false ? false : {
					formatter: () => this.state.name,
					style: {
						textAlign: 'center',
						fontFamily: config.style.labelFontFamily || 'FangSong',
						fill: config.style.labelFontColor || '#999',
						fontSize: config.style.labelFontSize || 15,
						fontWeight: config.style.labelFontBold ? 'bold' : 'normal',
						fontStyle: config.style.labelFontItalic ? 'italic' : 'normal',
					},
					offsetY: -30
				},
				content: config.style.isShowLiquidValue === false ? false : {
					style: {
						textAlign: 'center',
						fontFamily: config.style.liquidValueFontFamily || 'FangSong',
						fill: config.style.liquidValueFontColor || '#000',
						fontSize: config.style.liquidValueFontSize || 32,
						fontWeight: config.style.liquidValueFontBold ? 'bold' : 'normal',
						fontStyle: config.style.liquidValueFontItalic ? 'italic' : 'normal',
					},
					offsetY: -25,
					formatter: ( { percent } ) => {
						return `${ ( percent * 100 ).toFixed( isNaN( config.style.liquidValueFixed ) ? 2 : config.style.liquidValueFixed ) }${ config.style.isShowLiquidPercent === false ? '' : '%' }`;
					}
				},
			},
			liquidStyle: {
				fill: config.style.liquidWaveColor || '#0CCC98',
				stroke: config.style.liquidWaveColor || '#0CCC98'
			}
		};
	}

	async getConditionData() {
		let { config } = this.props;

		if ( config.data.valueFields && config.data.valueFields.length > 0 ) {
			const x = config.data.valueFields.map( v => {
				return {
					aggregateType: v.aggregateType,	//	度量的聚合类型
					formatType: '',	// 维度的聚合类型
					alias: v.title,
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: v.orderType,	//	排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit || '',
					precision: v.precision
				};
			} );
			// const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];
			
			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );
			
			const request = {

				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: config.data.tableCode,
						x: x,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'water'
				},
				type: 'quota',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success && pageResponse.data.data.rows && pageResponse.data.data.rows.length > 0 ) {
				return pageResponse.data.data.rows[ 0 ];
			}
		}

		return {
			name: this.state.name,
			percent: this.state.percent
		};

	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}


	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config, chartLayout } = this.props;
		let changeObj = Object.create( null );

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevProps.config.data.valueFields ) !== JSON.stringify( config.data.valueFields ) ||
			JSON.stringify( prevProps.config.data.filterFields ) !== JSON.stringify( config.data.filterFields ) ||
			JSON.stringify( prevProps.config.data.filterConditions ) !== JSON.stringify( config.data.filterConditions ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies )
		) {
			changeObj.needDataChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		//判断是否因宽高改变重新适应布局
		if ( prevProps.chartLayout.w !== chartLayout.w || prevProps.chartLayout.h !== chartLayout.h ) {
			changeObj.needLayoutChange = true;
		}

		return changeObj;

	}

	initEvent = async () => {
		const data = await this.getConditionData();
		this.setState( {
			name: data.name,
			percent: data.percent,
			isRender: true
		}, () => {
			const liquidPlot = new Liquid( this.props.id, this.getConfig() );
			liquidPlot.render();
			this.setState( {
				chartEl: liquidPlot
			} );
		} );
	};

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {

		if ( snapshot.needStyleChange ) this.state.chartEl.update( this.getConfig() );

		if ( snapshot.needDataChange ) {
			const newData = await this.getConditionData();

			this.setState( {
				name: newData.name,
				percent: newData.percent
			}, () => {
				this.state.chartEl.changeData( newData.percent );
			} );

		}
	}

	render() {
		return <div id={ this.props.id } style={ { height: '100%' } }></div>;
	}

	componentWillUnmount(): void {
		PubSub.unsubscribe( this.state.eventToken );
	}
};
